package myGUI;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;

import myVPN.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.net.UnknownHostException;
import java.util.List;
import javax.swing.JScrollBar;

import Encryption.Aes;

public class ClientGUI extends JFrame {

	private JPanel contentPane;
	private JTextField txt_HostName;
	private JTextField txt_PortNum;
	private JTextField txt_SecretVal;
	
	private JTextArea txt_ToSend;
	private JTextArea txt_ToReceive;
	private JTextArea txt_ActualSent;
	private JTextArea txt_ActualReceived;
	
	private JButton btnConnect;
	private JButton btnSend;
	private JButton btnContinue;
	
	private TCPClient tcpClient;
	private UpdateMessageTask updateTask;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					ClientGUI frame = new ClientGUI();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public ClientGUI() {
		super("ClientGUI");
		
		tcpClient = new TCPClient();
		setTitle("VPN - Client");
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 780, 400);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);
		
		JPanel panel = new JPanel();
		contentPane.add(panel, BorderLayout.CENTER);
		panel.setLayout(null);
		
		JLabel label = new JLabel("Client Mode");
		label.setBounds(10, 11, 738, 14);
		panel.add(label);
		
		JLabel label_1 = new JLabel("Host Name (IP address):");
		label_1.setBounds(10, 35, 168, 14);
		panel.add(label_1);
		
		JLabel label_2 = new JLabel("Port Number:");
		label_2.setBounds(10, 60, 168, 14);
		panel.add(label_2);
		
		JLabel label_3 = new JLabel("Shared Secret Value:");
		label_3.setBounds(10, 85, 168, 14);
		panel.add(label_3);
		
		JLabel label_4 = new JLabel("Data to be Sent");
		label_4.setBounds(10, 144, 118, 14);
		panel.add(label_4);
		
		JLabel label_5 = new JLabel("Data as Received");
		label_5.setBounds(10, 270, 118, 14);
		panel.add(label_5);
		
		txt_HostName = new JTextField();
		txt_HostName.setColumns(10);
		txt_HostName.setBounds(188, 32, 298, 20);
		panel.add(txt_HostName);
		
		txt_PortNum = new JTextField();
		txt_PortNum.setColumns(10);
		txt_PortNum.setBounds(188, 57, 298, 20);
		panel.add(txt_PortNum);
		
		txt_SecretVal = new JTextField();
		txt_SecretVal.setColumns(10);
		txt_SecretVal.setBounds(188, 82, 298, 20);
		panel.add(txt_SecretVal);
		
		btnConnect = new JButton("Connect");
		btnConnect.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				(updateTask = new UpdateMessageTask()).execute();
			}
		});
		btnConnect.setBounds(188, 113, 89, 23);
		panel.add(btnConnect);
		
		txt_ToSend = new JTextArea();
		txt_ToSend.setBounds(188, 139, 298, 86);
		panel.add(txt_ToSend);
		
		btnSend = new JButton("Send");
		btnSend.setEnabled(false);
		btnSend.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
				txt_ToReceive.setText("");
				txt_ActualReceived.setText("");
				
				try {
					tcpClient.setClientMessage(txt_ToSend.getText());
					tcpClient.sendMessage();
					txt_ActualSent.setText(tcpClient.getProcessedOut());
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		btnSend.setBounds(188, 236, 89, 23);
		panel.add(btnSend);
		
		txt_ToReceive = new JTextArea();
		txt_ToReceive.setEditable(false);
		txt_ToReceive.setBounds(188, 265, 298, 86);
		panel.add(txt_ToReceive);
		
		txt_ActualReceived = new JTextArea();
		txt_ActualReceived.setEditable(false);
		txt_ActualReceived.setBounds(496, 224, 254, 128);
		panel.add(txt_ActualReceived);
		
		JLabel label_6 = new JLabel("Actual Data Received:");
		label_6.setBounds(496, 199, 252, 14);
		panel.add(label_6);
		
		txt_ActualSent = new JTextArea();
		txt_ActualSent.setEditable(false);
		txt_ActualSent.setBounds(496, 60, 254, 128);
		panel.add(txt_ActualSent);
		
		JLabel label_7 = new JLabel("Actual Data Sent:");
		label_7.setBounds(496, 35, 155, 14);
		panel.add(label_7);
		
		btnContinue = new JButton("Continue");
		btnContinue.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				txt_ActualSent.setText("");
				txt_ToReceive.setText("");
				txt_ActualReceived.setText("");
				txt_ToSend.setText("");
				
				if (!tcpClient.isProtocolSuccess()){		

					try {
						if (tcpClient.getCurrSentIdx()==0)
						{
							tcpClient.doKeyExchangeOne();
							txt_ActualSent.setText(tcpClient.getProcessedOut());
							txt_ToSend.setText(tcpClient.getClientMessage());

						}
						else if (tcpClient.getCurrSentIdx()==1)
						{}
						else if (tcpClient.getCurrSentIdx()==2){
							tcpClient.doKeyExchangeTwo();
							txt_ActualSent.setText(tcpClient.getProcessedOut());
							txt_ToSend.setText(tcpClient.getClientMessage());
							
							tcpClient.setProtocolSuccess(true);
							//txt_ToReceive.setText("connection established...");
							btnSend.setEnabled(true);
						}
						else if (tcpClient.getCurrSentIdx()==3)
						{}
						
						
						
					} catch (Exception e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					
				}
				
			}
		});
		btnContinue.setBounds(661, 31, 89, 23);
		panel.add(btnContinue);
		
		JScrollBar scrollBar = new JScrollBar();
		scrollBar.setBounds(188, 139, 17, 86);
		panel.add(scrollBar);
		
		JButton btnClearWindow = new JButton("Clear");
		btnClearWindow.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				txt_ActualSent.setText("");
				txt_ToReceive.setText("");
				txt_ActualReceived.setText("");
				txt_ToSend.setText("");
			}
		});
		btnClearWindow.setBounds(311, 113, 89, 23);
		panel.add(btnClearWindow);
	}
	
	private class UpdateMessageTask extends SwingWorker<Void, String> {

		@Override
        protected Void doInBackground() {
			tcpClient.setProtocolSuccess(false);

			btnConnect.setEnabled(false);
			
			String hostname = txt_HostName.getText();
			int portnum = Integer.parseInt(txt_PortNum.getText());
			String secretVal = txt_SecretVal.getText();
			
			try {
				tcpClient.setHostName(hostname);
				tcpClient.setPortNum(portnum);
				tcpClient.setSecretVal(secretVal);
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}						
			
			try {
				tcpClient.startConnection();
				tcpClient.streamData();
				tcpClient.setCurrReceiveIdx(0);
				tcpClient.setCurrSentIdx(0);
				
				String from = "";
				while (true) {
					try {
						tcpClient.readMessage();
						from = tcpClient.getServerMessage();						
						if (from != null){

							if (tcpClient.getCurrReceiveIdx()==1)
							{
								//String delims = "/";
								//String[] tokens = from.split(delims);
								//String Rb = tokens[0];
								//tcpClient.setRbFromServer(Rb);
								//tcpClient.setEncrypted(tokens[1]);
								//tcpClient.setProcessedIn(Rb + "/" + Aes.DecryptNoPadding(tcpClient.getEncrypted()));
								//tcpClient.setProcessedIn(Rb + "/" + tcpClient.getEncrypted());
								
								tcpClient.setCurrReceiveIdx(2);
								tcpClient.setCurrSentIdx(2);
							}
							
							if (tcpClient.isProtocolSuccess()){
								if (tcpClient.getCurrReceiveIdx()!=1){
									txt_ActualReceived.setText(tcpClient.getServerMessage());
									tcpClient.setProcessedIn(tcpClient.getProcessedIn());//should be decrypted
									txt_ToReceive.setText(tcpClient.getProcessedIn());		
								}			
							}
								
							else{
								txt_ToReceive.setText(tcpClient.getProcessedIn());
								txt_ActualReceived.setText(tcpClient.getServerMessage());
							}
								
						}

					} catch (Exception e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					publish(new String(from));
				}
			} catch (Exception e1) {
				// TODO: handle exception
				e1.printStackTrace();
			}
			return null;
        }
 
//        @Override
//        protected void process(List<String> strs) {
//        	String str = strs.get(strs.size() - 1);
//        	if (str != null){
//        		txt_ToReceive.setText(str);
//        	}
//            
//        }
    }
}
